﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Nature.Toolkit.GMix
{
    /// <summary>
    /// Projection of all the Component items found in the Expression object 
    /// onto the particular set of thermo-chemical data
    /// </summary>
    public class MixProjection
    {
        #region Private Fields
        CompositionObject[] m_resolution;
        double[] m_parameterValues;
        #endregion
        
        internal MixProjection(ExpressionInfo expression) 
        {            
            this.Expression = expression;
            m_resolution = new CompositionObject[expression.Components.Length];
            m_parameterValues = new double[expression.Parameters.Length];            
        }

        internal void Fill()
        {
            Expression.Fill(this);
        }
        
        internal ExpressionInfo Expression
        {
            get;
            private set;
        }

        internal CompositionObject this[int compositionIndex]
        {
            get 
            {
                return m_resolution[compositionIndex];
            }
            set 
            {
                m_resolution[compositionIndex] = value;
            }
        }

        internal double GetParameterValue(int parameterIndex)
        {
            return m_parameterValues[parameterIndex];
        }

        internal void SetParameterValue(int parameterIndex, double parameterValue)
        {
            m_parameterValues[parameterIndex] = parameterValue;
        }

        public ReadOnlyArray<double> ParameterValues { get { return m_parameterValues; } }

        public CompositionObject this[string componentName]
        {
            get 
            {
                int componentIndex = Expression.ComponentIndex(componentName.ToLower());
                return m_resolution[componentIndex];
            }
        }

        public ReadOnlyArray<CompositionObject> CompositionObjects { get { return m_resolution; } }

        internal void Add(CompositionObject comp)
        {
            m_resolution[comp.Component.ComponentIndex] = comp;
            if (comp.Component.IsRoot)
            {
                comp.Projection = this;
            }
        }
    }
}
